/*
 * =====================================================================================
 *
 *       Filename:  shapeGrammar.cpp
 *
 *    Description:  Class implementation of shape grammar
 *
 *        Version:  1.0
 *        Created:  30/06/12 15:43:32
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Moos Hueting (mh), mooshueting@gmail.com
 *   Organization:  UCL
 *
 * =====================================================================================
 */
#include "shapeGrammar.h"

void ShapeGrammar::generateRules() {
    for (int i=0; i < 100; i++) {
        addRule(Rule(lib)); // generate random rule and add to grammar
    }
    // make sure we have at least one initial and final rule
    Rule init(lib);
    init.setInitial();
    Rule final(lib);
    final.setFinal();

    addRule(init);
    addRule(final);

}

Character ShapeGrammar::generateCharacter(int sx, int sy) {
    Rule curRule = getRandomInitialRule();

    // initialize empty character
    Character c(sx, sy);
    
    // apply random initial rule
    c.applyInitialRule(curRule);

    // loop until a final rule is found
    while (!(curRule.isFinal())) {
        vector<Rule> appRules;
        Segment curSeg;

        while (appRules.size() == 0) {
            // select segment
            curSeg = c.getRandomSegment();
            
            // get applicable rules, if any
            appRules = applicableRules(curSeg);
        }

        // select rule
        curRule = appRules.at((int)(appRules.size()-1)*((float)rand()/RAND_MAX));

        // apply rule
        c.applyRule(curRule, curSeg);
    }
    // return character
    c.render();

    return c;
}

Rule ShapeGrammar::getRandomRule() {
    return getRule((int)getSize()*((float)rand()/RAND_MAX));
}

Rule ShapeGrammar::getRandomInitialRule() {
    vector<Rule> initRules;

    for (int i=0; i < getSize(); i++) {
        if (getRule(i).isInitial())
            initRules.push_back(getRule(i));
    }

    return initRules.at((int)initRules.size()*((float)rand()/RAND_MAX));
}

vector<Rule> ShapeGrammar::applicableRules(Segment seg) {
    vector<Rule> appRules;

    for (int i=0; i < getSize(); i++) {
        if (getRule(i).getInput().getName() == seg.getName())
            appRules.push_back(getRule(i));
    }

    return appRules;
}
